import * as Cesium from "cesium";
import BaseClass from "../base/BaseClass";

/**
 * 图层基类
 * @class LayerBase
 * @extends BaseClass
 */
class LayerBase extends BaseClass {
  /**
   * 图层类型
   * @readonly
   * @type {String}
   */
  _type = null;

  /**
   * 图层id
   * @readonly
   * @type {String}
   */
  _id = null;

  /**
   * 图层名称
   * @readonly
   * @type {String}
   */
  _name = null;

  /**
   * 图层备注
   * @readonly
   * @type {String}
   */
  _remarks = null;

  /**
   * 图层是否显示
   * @readonly
   * @type {Boolean}
   */
  _show = true;

  /**
   * 构造函数
   * @param {Object} options 配置选项
   * @param {Cesium.Viewer} options.viewer 场景viewer对象
   * @param {String} [options.id] 图层id，必须唯一，默认自动创建
   * @param {String} [options.name] 图层名称
   * @param {String} [options.remarks] 图层备注
   * @param {Boolean} [options.show=true] 图层是否显示
   */
  constructor(options) {
    super();

    // 初始化配置选项
    this._options = Object.assign(
      {},
      {
        show: true,
      },
      options
    );

    // 验证必需参数
    if (!this._options.viewer) {
      throw new Error("options.viewer is required");
    }

    // 初始化属性
    this._viewer = this._options.viewer;
    this._type = this.constructor.name;
    this._id = this._options.id || Cesium.createGuid();
    this._name = this._options.name || "";
    this._remarks = this._options.remarks || "";
    this._show = !!this._options.show;
    this._destroyed = false;
  }

  /**
   * 图层id
   * @readonly
   * @type {String}
   */
  get id() {
    return this._id;
  }

  /**
   * 获取或设置图层名称
   * @type {String}
   */
  get name() {
    return this._name;
  }

  set name(value) {
    this._name = value;
  }

  /**
   * 获取或设置图层备注
   * @type {String}
   */
  get remarks() {
    return this._remarks;
  }

  set remarks(value) {
    this._remarks = value;
  }

  /**
   * 获取或设置图层是否显示
   * @type {Boolean}
   */
  get show() {
    return this._show;
  }

  set show(value) {
    this._show = !!value;
  }

  /**
   * 图层类型
   * @readonly
   * @type {String}
   */
  get type() {
    return this._type;
  }

  /**
   * 销毁对象
   * @override
   * @inheritDoc
   */
  destroy() {
    if (this.isDestroyed()) {
      return;
    }

    this._options = null;
    // this._viewer = null;
    this._id = null;
    this._name = null;
    this._remarks = null;
    this._show = null;
    this._type = null;
    this._destroyed = true;

    super.destroy();
  }

  /**
   * 下载到本地
   * @param {String} name 文件名称
   */
  downloadToLocalFile(name) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    const data = this.toGeoJson();
    const jsonStr = JSON.stringify(data, null, 2);
    const blob = new Blob([jsonStr], { type: "application/json" });
    const url = URL.createObjectURL(blob);

    const link = document.createElement("a");
    link.href = url;
    link.download =
      name || `${this._name || "layer"}_${new Date().getTime()}.json`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  }

  /**
   * 从json数据中加载
   * 将清空已有数据，并从数据中读取并设置图层相关属性，比如id、name等
   * @param {Object} json json数据，必须是toGeoJson()转出的数据
   * @returns {Promise}
   */
  async loadFromGeoJson(json) {
    if (this.isDestroyed()) {
      return Promise.reject(new Error("Object has been destroyed"));
    }

    try {
      // 从json中读取图层属性
      if (json.id) {
        this._id = json.id;
      }
      if (json.name) {
        this._name = json.name;
      }
      if (json.remarks) {
        this._remarks = json.remarks;
      }
      if (typeof json.show === "boolean") {
        this._show = json.show;
      }

      // 触发加载完成事件
      this.fire("loadComplete");
      return Promise.resolve();
    } catch (error) {
      // 触发加载失败事件
      this.fire("loadError", error);
      return Promise.reject(error);
    }
  }

  /**
   * 从本地文件加载
   * 将清空已有数据，并从数据中读取并设置图层相关属性，比如id、name等
   * @returns {Promise}
   */
  async loadFromLocalFile() {
    if (this.isDestroyed()) {
      return Promise.reject(new Error("Object has been destroyed"));
    }

    return new Promise((resolve, reject) => {
      const input = document.createElement("input");
      input.type = "file";
      input.accept = "application/json";

      input.onchange = (event) => {
        const file = event.target.files[0];
        if (!file) {
          reject(new Error("No file selected"));
          return;
        }

        const reader = new FileReader();
        reader.onload = async (e) => {
          try {
            const json = JSON.parse(e.target.result);
            await this.loadFromGeoJson(json);
            resolve();
          } catch (error) {
            this.fire("loadError", error);
            reject(error);
          }
        };

        reader.onerror = (error) => {
          this.fire("loadError", error);
          reject(error);
        };

        reader.readAsText(file);
      };

      input.click();
    });
  }

  /**
   * 从指定的url加载
   * 将清空已有数据，并从数据中读取并设置图层相关属性，比如id、name等
   * @param {String} url 数据地址，必须是toGeoJson()转出的数据
   * @returns {Promise}
   */
  async loadFromUrl(url) {
    if (this.isDestroyed()) {
      return Promise.reject(new Error("Object has been destroyed"));
    }

    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const json = await response.json();
      await this.loadFromGeoJson(json);
      return Promise.resolve();
    } catch (error) {
      this.fire("loadError", error);
      return Promise.reject(error);
    }
  }

  /**
   * 转换成json
   * @returns {JSON} Geojson数据
   */
  toGeoJson() {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    return {
      type: "FeatureCollection",
      properties: {
        id: this._id,
        name: this._name,
        remarks: this._remarks,
        show: this._show,
        type: this._type,
        version: "1.0",
      },
      features: [],
    };
  }

}

export default LayerBase;
